<template>
  <div class="login-body">
    <div class="bg"></div>
    <div class="login-panel">
      <el-form
        class="login-register"
        :model="formData"
        :rules="rules"
        ref="formDataRef"
        @submit.prevent
      >
        <div class="login-title">超级云盘</div>
        <!-- 邮箱 -->
        <el-form-item prop="email">
          <el-input
            size="large"
            clearable
            placeholder="请输入邮箱"
            v-model.trim="formData.email"
            maxLength="150"
          >
            <template #prefix>
              <span class="iconfont icon-account"></span>
            </template>
          </el-input>
        </el-form-item>

        <!-- 注册或重置密码时显示内容 -->
        <div v-if="opType == 0 || opType == 2">
          <!-- 邮箱验证码 -->
          <el-form-item prop="emailCode">
            <div class="send-email-panel">
              <el-input
                size="large"
                placeholder="请输入邮箱验证码"
                v-model.trim="formData.emailCode"
              >
                <template #prefix>
                  <span class="iconfont icon-checkcode"></span>
                </template>
              </el-input>
              <el-button
                class="send-email-btn"
                type="primary"
                size="large"
                @click="showSendEmailCodeDialog"
                >获取验证码</el-button
              >
            </div>
            <el-popover placement="left" :width="300" trigger="click">
              <div>
                <p>1、在垃圾邮箱中查找邮箱验证码</p>
                <p>2、将邮箱【xxx.qq.com】添加到白名单</p>
                <p>3、联系客服人员</p>
              </div>
              <template #reference>
                <span class="a-link" :style="{ 'font-size': '14px' }"
                  >未收到邮箱验证码？</span
                >
              </template>
            </el-popover>
          </el-form-item>

          <!-- 昵称，仅注册时显示 -->
          <el-form-item prop="nickName" v-if="opType == 0">
            <el-input
              size="large"
              placeholder="请输入昵称"
              v-model.trim="formData.nickName"
              maxLength="20"
            >
              <template #prefix>
                <span class="iconfont icon-account"></span>
              </template>
            </el-input>
          </el-form-item>

          <!-- 新密码，校验规则与登录密码不一样 -->
          <el-form-item prop="newPassword">
            <el-input
              type="password"
              size="large"
              placeholder="请输入密码"
              v-model.trim="formData.newPassword"
              show-password
            >
              <template #prefix>
                <span class="iconfont icon-password"></span>
              </template>
            </el-input>
          </el-form-item>

          <!-- 重复密码 -->
          <el-form-item prop="rePassword">
            <el-input
              type="password"
              size="large"
              placeholder="请再次输入密码"
              v-model.trim="formData.rePassword"
              show-password
            >
              <template #prefix>
                <span class="iconfont icon-password"></span>
              </template>
            </el-input>
          </el-form-item>
        </div>

        <!-- 登录密码，登录时显示 -->
        <el-form-item prop="password" v-if="opType == 1">
          <el-input
            type="password"
            size="large"
            placeholder="请输入密码"
            v-model.trim="formData.password"
            show-password
          >
            <template #prefix>
              <span class="iconfont icon-password"></span>
            </template>
          </el-input>
        </el-form-item>

        <!-- 验证码 -->
        <el-form-item prop="captchaCode">
          <div class="captcha-code-panel">
            <el-input
              size="large"
              placeholder="请输入验证码"
              v-model.trim="formData.captchaCode"
              @keyup.enter="doSubmit"
            >
              <template #prefix>
                <span class="iconfont icon-checkcode"></span>
              </template>
            </el-input>
            <img
              :src="getCaptchaCheckUrl"
              alt="验证码"
              class="captcha-code"
              @click="refreshCaptcha(0)"
            />
          </div>
        </el-form-item>

        <!-- 已有账号，注册时显示 -->
        <el-form-item v-if="opType == 0">
          <a href="javascript:void(0)" class="a-link" @click="switchPanel(1)"
            >已有账号？</a
          >
        </el-form-item>

        <!-- 记住我，登录时显示 -->
        <el-form-item v-if="opType == 1">
          <div class="rememberme-panel">
            <el-checkbox v-model="formData.rememberMe">记住我</el-checkbox>
          </div>
          <div class="no-account">
            <a href="javascript:void(0)" class="a-link" @click="switchPanel(2)"
              >忘记密码？</a
            >
            <a href="javascript:void(0)" class="a-link" @click="switchPanel(0)"
              >没有账号？</a
            >
          </div>
        </el-form-item>

        <!-- 去登录，找回密码时显示 -->
        <el-form-item v-if="opType == 2">
          <a href="javascript:void(0)" class="a-link" @click="switchPanel(1)"
            >去登录？</a
          >
        </el-form-item>

        <!-- 登录按钮 -->
        <el-form-item>
          <el-button
            type="primary"
            class="op-btn"
            size="large"
            @click="doSubmit"
          >
            <span v-if="opType == 0">注册</span>
            <span v-if="opType == 1">登录</span>
            <span v-if="opType == 2">重置密码</span>
          </el-button>
        </el-form-item>
        <div class="login-btn-qq" v-if="opType == 1">
          快捷登录<img src="@/assets/icon/qq.png" @click="qqLogin" />
        </div>
      </el-form>
    </div>

    <!-- 发送邮件验证码弹窗 -->
    <Dialog
      :show="smcDialogConfig.show"
      :title="smcDialogConfig.title"
      :buttons="smcDialogConfig.buttons"
      :showCancel="false"
      width="400px"
      @close="smcDialogConfig.show = false"
    >
      <el-form
        :model="smcFormData"
        :rules="rules"
        ref="smcFormDataRef"
        label-width="80px"
        @submit.prevent
      >
        <el-form-item label="邮箱">{{ formData.email }}</el-form-item>
        <el-form-item label="验证码" prop="captchaCode">
          <div class="captcha-code-panel">
            <el-input
              size="large"
              placeholder="请输入验证码"
              v-model="smcFormData.captchaCode"
            >
              <template #prefix>
                <span class="iconfont icon-checkcode"></span>
              </template>
            </el-input>
            <img
              :src="getCaptchaEmailUrl"
              class="captcha-code"
              @click="refreshCaptcha(1)"
            />
          </div>
        </el-form-item>
      </el-form>
    </Dialog>
  </div>
</template>
<script setup>
import { ref, reactive, getCurrentInstance, nextTick, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import md5 from "js-md5";

const { proxy } = getCurrentInstance();
const router = useRouter();
const route = useRoute();

const api = {
  sendEmailCode: "/sendEmailCode",
  register: "/register",
  login: "/login",
  resetPwd: "/resetPwd",
  qqLogin: "/qqLogin",
};

const formData = ref({});
const formDataRef = ref();

// 两次密码校验
const checkRePassword = (rule, value, callback) => {
  if (value != formData.value.newPassword) {
    callback(new Error(rule.message));
  } else {
    callback();
  }
};

// 参数校验规则
const rules = {
  email: [
    { required: true, message: "请输入邮箱" },
    { validator: proxy.Valid.email, message: "请输入正确的邮箱" },
  ],
  password: [{ required: true, message: "请输入密码" }],
  emailCode: [{ required: true, message: "请输入邮箱验证码" }],
  nickName: [{ required: true, message: "请输入昵称" }],
  newPassword: [
    { required: true, message: "请输入密码" },
    {
      validator: proxy.Valid.password,
      message: "密码必须包含数字、字母和特殊字符，长度至少8位",
    },
  ],
  rePassword: [
    { required: true, message: "请输入密码" },
    {
      validator: checkRePassword,
      message: "两次输入的密码不一致",
    },
  ],
  captchaCode: [{ required: true, message: "请输入图片验证码" }],
};

// 操作类型：0：注册；1：登录；2：重置密码
const opType = ref(1);

// 切换窗口
const switchPanel = (type) => {
  opType.value = type;

  resetForm();
};

const captchaUrl = proxy.globalInfo.captchaUrl;
// 发送验证码
const getCaptchaCheckUrl = ref(captchaUrl);
const getCaptchaEmailUrl = ref(captchaUrl);

// 刷新验证码
const refreshCaptcha = (type) => {
  if (type == 0) {
    getCaptchaCheckUrl.value =
      captchaUrl + "?type=" + type + "&time=" + new Date().getTime();
  } else {
    getCaptchaEmailUrl.value =
      captchaUrl + "?type=" + type + "&time=" + new Date().getTime();
  }
};

// 发送邮箱验证码弹窗相关
const smcFormData = ref({});
const smcFormDataRef = ref();

const smcDialogConfig = reactive({
  show: false,
  title: "发送邮箱验证码",
  buttons: [
    {
      type: "primary",
      text: "发送验证码",
      click: (e) => {
        sendEmailCode();
      },
    },
  ],
});

// 显示发送邮箱验证码弹窗
const showSendEmailCodeDialog = () => {
  formDataRef.value.validateField("email", (valid) => {
    if (!valid) {
      return;
    }

    smcDialogConfig.show = true;

    // 清空表单数据重新赋值
    nextTick(() => {
      refreshCaptcha(1);
      smcFormDataRef.value.resetFields();
      smcFormData.value = {
        email: formData.value.email,
      };
    });
  });
};

// 发送邮箱验证码
const sendEmailCode = () => {
  smcFormDataRef.value.validate(async (valid) => {
    if (!valid) {
      return;
    }

    const params = Object.assign({}, smcFormData.value);
    params.type = opType.value == 0 ? 0 : 1;
    let result = await proxy.Request({
      url: api.sendEmailCode,
      params: params,
      errorCallback: () => {
        refreshCaptcha(1);
      },
    });

    if (!result) {
      return;
    }
    proxy.Message.success("验证码发送成功，请登录邮箱查看");
    // 发送成功关闭弹窗
    smcDialogConfig.show = false;
  });
};

// 重置表单
const resetForm = () => {
  formDataRef.value.resetFields();
  formData.value = {};

  // 登录时从cookie取用户名密码赋值到表单
  if (opType.value == 1) {
    let cookieLoginInfo = proxy.VueCookies.get("loginInfo");
    if (cookieLoginInfo) {
      formData.value = cookieLoginInfo;
    }
  }
};

// 提交表单
const doSubmit = () => {
  formDataRef.value.validate(async (valid) => {
    if (!valid) {
      return;
    }
    let params = {};
    Object.assign(params, formData.value);

    // 注册或找回密码
    if (opType.value == 0 || opType.value == 2) {
      params.password = params.newPassword;
      delete params.newPassword;
      delete params.rePassword;
    }

    // 登录时从cookie中取密码
    if (opType.value == 1) {
      let cookieLoginInfo = proxy.VueCookies.get("loginInfo");
      let cookiePassword =
        cookieLoginInfo == null ? null : cookieLoginInfo.password;
      if (params.password != cookiePassword) {
        params.password = md5(params.password);
      }
    }
    let url = null;
    if (opType.value == 0) {
      url = api.register;
    } else if (opType.value == 1) {
      url = api.login;
    } else if (opType.value == 2) {
      url = resetPwd;
    }

    let result = await proxy.Request({
      url: url,
      params: params,
      errorCallback: () => {
        refreshCaptcha(0);
      },
    });
    if (!result) {
      return;
    }

    // 注册
    if (opType.value == 0) {
      proxy.Message.success("注册成功，请登录");
      switchPanel(1);
    } else if (opType.value == 1) {
      // 登录
      // 如果选择记住密码，则将用户密码记录到cookie
      if (params.rememberMe) {
        const loginInfo = {
          email: params.email,
          password: params.password,
          rememberMe: params.rememberMe,
        };
        // 保存7天
        proxy.VueCookies.set("loginInfo", loginInfo, "7d");
      } else {
        proxy.VueCookies.remove("loginInfo");
      }
      proxy.Message.success("登录成功");
      // 临时保持用户信息，关闭浏览器时删除
      proxy.VueCookies.set("userInfo", result.data, 0);

      // 重定向到原页面
      if (route.query.redirectUrl == "/login") {
        route.query.redirectUrl = "/";
      }
      const redirectUrl = route.query.redirectUrl || "/";
      router.push(redirectUrl);
    } else if (opType.value == 2) {
      // 重置密码
      proxy.Message.success("重置密码成功，请登录");
      switchPanel(1);
    }
  });
};

// qq登录
let qqLogin = async () => {
  try {
    let result = await proxy.Request({
      url: api.qqLogin,
      params: {
        redirectUrl: route.query.redirectUrl || "",
      },
    });

    if (!result) {
      return;
    }

    proxy.VueCookies.remove("userInfo");
    document.location.href = result.data;
  } catch (error) {
    console.error("Error during QQ login:", error);
    // 处理错误情况
  }
};
onMounted(() => {
  switchPanel(1);
});
</script>
<style lang="scss" scoped>
.login-body {
  min-height: calc(100vh);
  background-size: cover;
  background-image: url("../assets/images/login_bg.jpg");
  display: flex;

  .bg {
    flex: 1;
    background-position: center;
    background-size: 500px;
    background-repeat: no-repeat;
    background-image: url("../assets/images/login_img.png");
  }

  .login-panel {
    width: 400px;
    margin-right: 15%;
    margin-top: calc((100vh - 500px) / 2);

    .login-register {
      padding: 25px;
      background: #fff;
      border-radius: 5px;

      .login-title {
        text-align: center;
        font-size: 18px;
        font-weight: bold;
        margin-bottom: 20px;
      }

      .send-email-panel {
        display: flex;
        width: 100%;
        justify-content: space-between;

        .send-email-btn {
          margin-left: 5px;
        }
      }

      .remeberme-panel {
        width: 100px;
      }

      .no-account {
        width: 100%;
        display: flex;
        justify-content: space-between;
      }

      .op-btn {
        width: 100%;
      }
    }
  }

  .captcha-code-panel {
    width: 100%;
    display: flex;

    .captcha-code {
      margin-left: 5px;
      cursor: pointer;
    }
  }

  .login-btn-qq {
    margin-top: 20px;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;

    img {
      cursor: pointer;
      margin-left: 10px;
      width: 20px;
    }
  }
}
</style>
